# -*- coding: utf-8 -*-
 ##############################################
 ##                                            ##
 ##        Data model for Ventas package        ##
 ##                                             ##
 ##                                             ##
 ##              from Basiq Series              ##
 ##           by Críptidos Digitales            ##
 ##                 GPL (c)2008                 ##
  ##                                            ##
    ##############################################

"""
"""

import datetime

from decimal import Decimal


from baseModel import *





def addSale(data):
    print "ventas.model.addSale()"

    ## Se asume que no hay proceso creado para esta transacción, los pedidos se generan solamente en los servicios y ahi son procesados.

    currentDateTime = datetime.datetime.today()

    ## Proceso
    proceso = set('procesos', tipo=u'venta', fecha=data['fecha'], status=u'abierto')

    ## Cliente
    if not data['rol_id']:
        """ Acomoda los datos recibidos de la igu y los registra """
        """ Se apoya en el módulo principal man """
        datosCliente = data.pop('cliente')

        print datosCliente

        f=g

        # data['rol_id'] = man.rolI(**datosCliente).id
        data['rol_id'] = model.getPerson(**datosCliente)

    ## Documento
    documento = set('documentos', tipo_id=data['tipoDocumento_id'], folio=data['folioDocumento'], fecha=data['fecha'], rol_id=data['rol_id'], subtotal=data['subtotal'], descuento=data['descuento'], impuesto=data['impuesto'], total=data['total'], fechaalta=currentDateTime, status=u'cerrado')
    #~ print "-- documento :", documento

    costoTotal = Decimal('0.00')

    ## Partidas
    for indexPartida, item in enumerate(data['partidas']):
        costoTotal += item['costo'] * item['cantidad']
        partida = set('partidasdocumento', documento_id=documento['documento_id'], producto_id=item['producto_id'], cantidad=item['cantidad'], costo=item['costo'], precio=item['precio'], precioneto=item['precioneto'], descuento=item['descuento'], impuesto=item['impuesto'], status=u'cerrada')
        #~ print "-- partida %s :" % indexPartida, partida

    ## Operacion (se crea despues de calcular el costoTotal)
    operacion = set('operaciones', cuenta=u"inventarios", operacion_tipo=u"salida", fecha=data['fecha'], monto=costoTotal, status=u'cerrada')
    #~ print "-- entrada :", operacion

    set('proceso_operacion', proceso_id=proceso['proceso_id'], operacion_id=operacion['operacion_id'])
    set('operaciones_documentos', operacion_id=operacion['operacion_id'], documento_id=documento['documento_id'])

    ## PAGO
    if data['pago']:


        if data['pago']['tipo'] == u'efectivo':

            operacionPago = set('operaciones', cuenta=u'caja', operacion_tipo=u'cobro', fecha=data['pago']['fecha'], monto=-data['total'], referencia='%s' % data['pago']['cambio'], status=u'cerrada')

            set('proceso_operacion', proceso_id=proceso['proceso_id'], operacion_id=operacionPago['operacion_id'])

    consolidaSalidas(data['partidas'])

    modificaFolio(data['folioDocumento'], data['tipoDocumento_id'])

    return documento





def activePriceRules():
    data = getAttributes(grupo='rangoPrecioProducto', order='referencia')
    active = []
    for rule in data:
        if rule['referencia'][1] == 'a':
            active.append(rule)
    return active


def capturaDePagoObligatoria():
    data = getAttribute(grupo=u'ventas', nombre=u'capturaPagoObligatoria')['valor']
    if data:
        value = True
    else:
        value = False
    return value


def condicionesPago():
    registros = getAttributes(grupo=u'condicionesPago')
    return registros


def consolidaSalidas(partidas):
    products = []
    for partida in partidas:
        product = getOne('productos', id=partida['producto_id'])
        product['actual'] -= partida['cantidad']

        products.append(product)

    for product in products:
        set('productos', id=product['id'], actual=product['actual'])


def dateChangeAllowed():
    data = getAttribute(grupo=u'ventas', nombre=u'dateChangeAllowed')['valor']
    if data:
        value = True
    else:
        value = False
    return value


def defaultCustomer():
    customer = getRol(id=int(getAttribute(grupo=u'cliente', nombre=u'default')['valor']))
    return customer


def defaultDocumentType():
    documentType = getAttribute(grupo=u'tipoDocumentoVenta', nombre=u'default')
    return documentType


def folio(documentTypeId):
    # print "ventas.modelo.folio('%s')" % documentTypeId
    folio = getAttribute(grupo=u'folioDocumento', referencia=str(documentTypeId))['valor']
    length = len(folio)
    """
    if documentTypeId == u'factura':
        print 444
        folio = int(getAttribute(grupo=u'folioDocumento', nombre=u'ventaFiscal')['valor'])
        length = 5
    elif tipoDocumento == u'remisión':
        print 333
        folio = int(getAttribute(grupo=u'folioDocumento', nombre=u'ventaControl')['valor'])
        length = 5
    """
    folio = int(folio) + 1
    return str(folio).zfill(length)


def formasPago():
    registros = getAttributes(grupo=u'formaPago', order=u'referencia')
    return registros


def getLineas():
    lineas = getAttributes(grupo=u'líneaProducto')
    return lineas


def tiposDocumento():
    tipos = getAttributes(grupo='tipoDocumento', referenciaLIKE='venta')
    return tipos

    '''
    filtersBody = """x['grupo']=="tipoDocumento" and "venta" in x['referencia'] """
    exec("""data = [x for x in mainModel.session.attributes if %s]""" % filtersBody.rstrip('and '))
    return data
    '''





















def addCustomer(**data):                # To be used as getCustomer
    entidad = None
    entidadDict = {}
    if 'personalidad' in datos.keys(): entidadDict['personalidad'] = datos['personalidad']
    if 'nombre' in datos.keys(): entidadDict['nombre'] = datos['nombre']
    if 'nombre2' in datos.keys(): entidadDict['nombre2'] = datos['nombre2']
    if 'rfc' in datos.keys():   entidadDict['rfc'] = datos['rfc']
    if 'alias' in datos.keys(): entidadDict['alias'] = datos['alias']

    if entidadDict:
        if 'entidad_id' in datos.keys():
            entidad = session().query(Entidad).filter(Entidad.id==datos['entidad_id']).one()
        else:
            entidad = session().query(Entidad).filter_by(**entidadDict).first()
            if not entidad:
                entidad = Entidad(**entidadDict)
        entidad.setData(**entidadDict)
        session().add(entidad)
        session().flush()




def impuestoIncluido():
    return True


def modificaFolio(folio, tipoDocumento):
    #~ print "ventas.modelo.modificaFolio(%s)" % tipoDocumento
    if type(tipoDocumento) == int:
        tipoDocumento = getAttribute(id=tipoDocumento)['nombre']

    if tipoDocumento == u'remisión':
        setAttribute(grupo=u'folioDocumento', nombre=u'ventaControl', valor=unicode(folio))
    elif tipoDocumento == u'factura':
        setAttribute(grupo=u'folioDocumento', nombre=u'ventaFiscal', valor=unicode(folio))


@property
def salesCount():
    query("""SELECT count(*) FROM procesos WHERE tipo="venta" """)
    count = fetchone()
    print count
    f=g
    return count


def sales(**filters):
    if 'sumasDiarias' in filters.keys():
        fecha = filters['inicio']
        totales = []

        while fecha <= filters['termino']:
            ventas = salesForDate(fecha)
            total = Decimal("0.00")
            for venta in ventas:
                total += venta['total']
            totales.append({'fecha':fecha, 'total':total})
            fecha = fecha + datetime.timedelta(days=1)
        return totales

    else:

        command = """SELECT proceso_id,
    array_agg(ops.operacion_id) AS operaciones_id,
    array_agg(ops.operacion_tipo) AS operaciones_tipo,
    array_agg(ops.fecha) AS operaciones_fecha,
    array_agg(ops.monto) AS operaciones_monto,
    array_agg(ops.status) AS operaciones_status
FROM procesos
    JOIN proceso_operacion USING(proceso_id)

    JOIN (SELECT op.operacion_id, op.operacion_tipo, op.fecha, op.monto, op.status
        FROM operaciones AS op
        ) AS ops
    USING (operacion_id)

    JOIN operaciones_documentos USING (operacion_id)
    JOIN documentos USING (documento_id)
WHERE
GROUP BY proceso_id, procesos.fecha
ORDER BY procesos.fecha ASC
LIMIT 100
"""

        filtersText = "procesos.tipo='venta' AND "
        for filter in filters.keys():
            if filter == 'termino':
                filtersText += "documentos.fecha<='%s' AND " % filters['termino']
            elif filter == 'inicio':
                filtersText += "documentos.fecha>='%s' AND " % filters['inicio']
            elif filter == 'documentType':
                filtersText += "documentos.tipo_id=%s AND " % filters[filter]
            elif ' IN' in filter.upper():
                filtersText += "%s IN %s AND " % (filter.rstrip('IN'), filters[filter])

            elif type(filters[filter]) in (str, unicode, datetime.datetime):
                filtersText += "%s='%s' AND " % (filter, filters[filter])
            elif type(filters[filter]) in (list,):
                temp = ("%s" % filters[filter]).replace("[", "{").replace("]","}").replace("'", '"')
                filtersText += "%s='%s' AND " % (filter, temp)
            elif filters[filter] == None:
                filtersText += "%s is null AND " % filter
            else:
                filtersText += "%s=%s AND " % (filter, filters[filter])

        if filtersText:
            command = command.replace("WHERE", "WHERE %s " % filtersText.rstrip("AND "))
        else:
            command = command.replace("WHERE", "")

        #~ print command

        query(command)
        registros = fetchAll()

        return registros


def salesForDate(date):
    tipos = [getAttribute(grupo=u'tipoDocumento', nombre=u'factura')['id'], getAttribute(grupo=u'tipoDocumento', nombre=u'remisión')['id']]

    command = """SELECT documentos.total
    FROM procesos
    JOIN proceso_operacion USING(proceso_id)

    JOIN (SELECT op.operacion_id, op.operacion_tipo, op.fecha, op.monto, op.status
        FROM operaciones AS op
        ) AS ops
    USING (operacion_id)

    JOIN operaciones_documentos USING (operacion_id)
    JOIN documentos USING (documento_id)
WHERE procesos.tipo='venta' AND DATE(documentos.fecha)='%s' AND documentos.tipo_id IN (%s, %s)
ORDER BY procesos.fecha ASC""" % (date, tipos[0], tipos[1])

    # print command

    query(command)

    sales = fetchAll()

    return sales


def seImprimeComprobante():
    data = attribute(grupo=u'ventas', nombre=u'seImprimeComprobante')['valor']
    if data:
        value = True
    else:
        value = False

    return value



def initDb():
    #~ print "ventas.model.initDb(",
    try:
        version = int(getAttribute(grupo=u'ventas', nombre=u'versionBasedatos')['valor'])
    except:
        version = 0

    if version < 1:
        print "Inicializando Base de datos para ventas"
        registros = [
            {'code':1451, 'grupo':u'ventas', 'nombre':u'capturaPagoObligatoria', 'valor':u'0'},
            {'code':1453, 'grupo':u'ventas', 'nombre':u'seImprimeComprobante', 'valor':u'0'},
            {'code':1455, 'grupo':u'ventas', 'nombre':u'focusEnSeleccionDeProducto', 'valor':u'0'},
            {'code':1459, 'grupo':u'ventas', 'nombre':u'dateChangeAllowed', 'valor':u'0'},

            {'code':1471, 'grupo':u'ventas', 'nombre':u'useBarCode', 'valor':u'1'},
            {'code':1473, 'grupo':u'ventas', 'nombre':u'useAuxiliaryCode', 'valor':u'1'},
            {'code':1475, 'grupo':u'ventas', 'nombre':u'useLine', 'valor':u'1'},
            {'code':1477, 'grupo':u'ventas', 'nombre':u'useOwnCode', 'valor':u'1'}
            ]

        for registro in registros:
            setAttribute(**registro)

        ## Instituciones Bancarias
        lista = [
        [3, u'Banamex', u'Banco Nacional de México, S.A.', u'', u'BAN111111222', u'Isabel la Católica 44', u'Col. Centro Histórico, Del. Cuauhtémoc', u'México, D.F.', u'06000'],
        [7, u'Banco Santander', u'Banco Santander, S.A.', u'', u'SAN111111333', u'Prol. Paseo de la Reforma No. 500, Piso 4; Mód.401', u'Col. Lomas de Santa Fe', u'México, D.F.', u'01219'],
        [11, u'BBVA Bancomer', u'BBVA Bancomer, S.A.', u'', u'BBV111111222', u'Av. Universidad No. 1200, 2º Piso', u'Col. Xoco', u'México, D.F.', u'03339'],
        [15, u'HSBC', u'HSBC México, S.A.', u'', u'HSB111111222', u'Paseo de la Reforma No. 347', u'Col. Juárez', u'México, D.F.', u'06600'],
        [19, u'ScotiaBank', u'Scotiabank, S.A.', u'', u'SCO111111222', u'Blvd. Manuel Ávila Camacho No. 1 Piso 19', u'Col. Lomas de Chapultepec', u'México, D.F.', u'11009'],
        ]

        setAttribute(grupo=u'ventas', nombre=u'versionBasedatos', valor=u"1")
        version = 1

    if version < 2:
        setAttribute(code=1477, grupo=u'ventas', nombre=u'useOwnCode', valor=u'1')

        setAttribute(grupo=u'ventas', nombre=u'versionBasedatos', valor=u'2')
        version = 2

